package artandco.dao;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

/**
 * GenericDaoImpl.java
 * 
 * @version 1.0
 * @date 26 mai 2011
 * @param <T>
 * @param <PK>
 */
public class GenericDaoImpl<T, PK extends Serializable> implements GenericDao<T, PK> {

	private EntityManager em;

	private EntityManagerFactory emf;

	private EntityTransaction tx;

	private Class<T> type;

	/**
	 * Constructeur
	 * 
	 * @param type
	 * @param emf
	 */
	public GenericDaoImpl(Class<T> type, EntityManagerFactory emf) {
		this.type = type;
		this.emf = emf;
		this.em = emf.createEntityManager();
		tx = em.getTransaction();
	}

	/**
	 * getEmf
	 * 
	 * @return EntityManagerFactory
	 */
	public EntityManagerFactory getEmf() {
		return emf;
	}

	/**
	 * create
	 * 
	 * @param o
	 * @see artandco.dao.GenericDao#create(java.lang.Object)
	 */
	public void create(T o) {
		tx.begin();
		em.persist(o);
		tx.commit();
	}

	/**
	 * read
	 * 
	 * @param id
	 * @return
	 * @see artandco.dao.GenericDao#read(java.io.Serializable)
	 */
	public T read(PK id) {
		return (T) em.find(type, id);
	}

	/**
	 * readAll
	 * 
	 * @return
	 * @see artandco.dao.GenericDao#readAll()
	 */
	public List<T> readAll() {
		String HQL = "select o from " + type.getName().substring(17) + " o";
		return em.createQuery(HQL).getResultList();
	}

	/**
	 * update
	 * 
	 * @param o
	 * @see artandco.dao.GenericDao#update(java.lang.Object)
	 */
	public void update(T o) {
		tx.begin();
		em.merge(o);
		tx.commit();
	}

	/**
	 * delete
	 * 
	 * @param o
	 * @see artandco.dao.GenericDao#delete(java.lang.Object)
	 */
	public void delete(T o) {
		tx.begin();
		em.remove(o);
		tx.commit();
	}

	/**
	 * refresh
	 * 
	 * @param o
	 */
	public void refresh(T o) {
		em.refresh(o);
	}

	/**
	 * execute
	 * 
	 * @param HQL
	 * @return List<T>
	 */
	public List<T> execute(String HQL) {
		return em.createQuery(HQL).getResultList();
	}

}